home *** CD-ROM | disk | FTP | other *** search
- /*
- File: BetterFindFolder.cpp
-
- Contains: xxx put contents here xxx
-
- Owned by: Nick Pilch
-
- Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 6/23/96 NP 10002: Launch time speedups.
- <1> 6/21/96 NP first checked in
-
- To Do:
- */
-
- /*
- ** (C) Copyright 1995-1996 Damon Cokenias All Rights Reserved
- ** Permission is granted to use and distribute this source code freely so long
- ** as this copyright notice is not changed.
- */
-
- #ifndef BETTERFINDFOLDER_H
- #include "BetterFindFolder.h"
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __FINDER__
- #include <Finder.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=mac68k
- #endif
-
- typedef struct {
- OSType parentFolderType; // parent folder (ie. kPreferencesFolderType)
- Str32 folderName; // name of folder
- Boolean onSystemDisk; // true means folder is on system disk
- short iconID; // 0 means no icon
- } BetterFolderRec, **BetterFolderHandle;
-
- #define kFolderResType 'BFld'
- #define kMagicIconFileName "\pIcon\015"
-
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=reset
- #endif
-
- static
- OSErr FindApplicationFolder (short* vRefNum, long* dirID)
- {
- static Boolean doneIt = false;
- static short cachedVRefNum;
- static long cachedDirID;
-
- if (doneIt) {
- *vRefNum = cachedVRefNum;
- *dirID = cachedDirID;
- return noErr;
- }
-
- FCBPBRec pb;
-
- pb.ioNamePtr = nil;
- pb.ioRefNum = LMGetCurApRefNum ();
- pb.ioFCBIndx = 0;
-
- OSErr error = PBGetFCBInfoSync (&pb);
- if (error)
- return error;
-
- doneIt = true;
- *vRefNum = cachedVRefNum = pb.ioFCBVRefNum;
- *dirID = cachedDirID = pb.ioFCBParID;
-
- return noErr;
- }
-
- static
- OSErr CreateCustomFolderIcon (short vRefNum, long dirID, short iconID)
- {
- static OSType resourceTypes [6] = { 'ICN#', 'icl8', 'icl4', 'ics#', 'ics8', 'ics4' };
- OSErr error;
-
- /* create the icon file and make it invisible */
- error = HCreate (vRefNum, dirID, kMagicIconFileName, 0, 0);
- if (error)
- return error;
-
- HCreateResFile (vRefNum, dirID, kMagicIconFileName);
-
- CInfoPBRec pb;
-
- pb.hFileInfo.ioNamePtr = kMagicIconFileName;
- pb.hFileInfo.ioVRefNum = vRefNum;
- pb.hFileInfo.ioFDirIndex = 0;
- pb.hFileInfo.ioDirID = dirID;
-
- error = PBGetCatInfoSync (&pb);
- if (error)
- return error;
-
- pb.hFileInfo.ioFlFndrInfo.fdFlags |= kIsInvisible;
- pb.hFileInfo.ioDirID = dirID;
- error = PBSetCatInfoSync (&pb);
- if (error)
- return error;
-
- /* copy the icon resources into the icon file */
- short oldResFile = CurResFile ();
- short iconResFile = HOpenResFile (vRefNum, dirID, kMagicIconFileName, fsRdWrPerm);
- if (iconResFile == -1)
- return ResError ();
-
- Boolean foundAtLeastOne = false;
-
- for (int i = 0; (i < 6) && (error == noErr); ++i) {
- UseResFile (oldResFile);
- Handle iconHandle = GetResource (resourceTypes [i], iconID);
- if (iconHandle) {
- foundAtLeastOne = true;
- DetachResource (iconHandle);
- UseResFile (iconResFile);
- AddResource (iconHandle, resourceTypes [i], kCustomIconResource, "\p");
- error = ResError ();
- }
- }
-
- CloseResFile (iconResFile);
- UseResFile (oldResFile);
-
- if (error)
- return error;
-
- if (foundAtLeastOne == false)
- return resNotFound;
-
- /* finally, set the custom icon bit of the folder */
- Str63 folderName;
-
- pb.hFileInfo.ioNamePtr = folderName;
- pb.hFileInfo.ioVRefNum = vRefNum;
- pb.hFileInfo.ioFDirIndex = -1;
- pb.hFileInfo.ioDirID = dirID;
-
- error = PBGetCatInfoSync (&pb);
- if (error)
- return error;
-
- pb.hFileInfo.ioFlFndrInfo.fdFlags |= kHasCustomIcon;
-
- pb.hFileInfo.ioNamePtr = nil;
- pb.hFileInfo.ioDirID = dirID;
-
- error = PBSetCatInfoSync (&pb);
-
- return error;
- }
-
- static
- OSErr CreateLocalFolder (short vRefNum, long dirID, BetterFolderRec* folderRecord,
- long* newDirID)
- {
- HParamBlockRec pb;
-
- pb.ioParam.ioNamePtr = folderRecord -> folderName;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.fileParam.ioDirID = dirID;
-
- OSErr error = PBDirCreateSync (&pb);
- if (error)
- return error;
-
- *newDirID = pb.fileParam.ioDirID;
- if (folderRecord -> iconID != 0)
- return CreateCustomFolderIcon (vRefNum, *newDirID, folderRecord -> iconID);
- else
- return noErr;
- }
-
- static
- OSErr FindLocalFolder (short vRefNum, long dirID, Boolean createFolder,
- BetterFolderRec* folderRecord, long* foundDirID)
- {
- CInfoPBRec pb;
-
- pb.hFileInfo.ioNamePtr = folderRecord -> folderName;
- pb.hFileInfo.ioVRefNum = vRefNum;
- pb.hFileInfo.ioFDirIndex = 0;
- pb.hFileInfo.ioDirID = dirID;
-
- OSErr error = PBGetCatInfoSync (&pb);
- if ((error == fnfErr) && createFolder)
- return CreateLocalFolder (vRefNum, dirID, folderRecord, foundDirID);
- else {
- *foundDirID = pb.hFileInfo.ioDirID;
- return error;
- }
- }
-
- static
- OSErr GetFolderRecord (OSType key, BetterFolderRec* folderRecord)
- {
- // Make a pascal string of key. Make sure the OSType is copied to an even address
- // for 68000 compatability. This means the length byte is actually at index 1, not 0
- unsigned char keyString [6];
- *((OSType*) &keyString [2]) = key;
- keyString [1] = 4;
-
- Handle res = GetNamedResource (kFolderResType, &keyString [1]);
- if (!res) {
- OSErr error = ResError ();
- return error ? error : resNotFound;
- }
-
- *folderRecord = **(BetterFolderHandle) res;
- return noErr;
- }
-
- pascal
- OSErr BetterFindFolder (short vRefNum, OSType folderType, Boolean createFolder,
- short* foundVRefNum, long* foundDirID)
-
- {
- OSErr error;
-
- if (folderType == kAppFolderType) {
- return FindApplicationFolder (foundVRefNum, foundDirID);
- } else {
- error = FindFolder (vRefNum, folderType, createFolder, foundVRefNum, foundDirID);
- if (error == fnfErr) {
-
- BetterFolderRec folderRecord;
-
- error = GetFolderRecord (folderType, &folderRecord);
- if (error)
- return error;
-
- error = BetterFindFolder (folderRecord.onSystemDisk ? kOnSystemDisk : vRefNum,
- folderRecord.parentFolderType, createFolder, foundVRefNum, foundDirID);
- if (error)
- return error;
-
- return FindLocalFolder (*foundVRefNum, *foundDirID, createFolder, &folderRecord,
- foundDirID);
- } else
- return error;
- }
- }
-
-
-
-
-
-
-
-
-